package com.jxt.detect;

import android.content.Context;

import com.amap.api.maps.AMapException;
import com.amap.api.maps.offlinemap.OfflineMapCity;
import com.amap.api.maps.offlinemap.OfflineMapManager;
import com.amap.api.maps.offlinemap.OfflineMapProvince;
import com.amap.api.maps.offlinemap.OfflineMapStatus;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

import io.flutter.Log;
import io.flutter.plugin.common.MethodChannel;

public class OfflineAmap implements OfflineMapManager.OfflineMapDownloadListener {
    private final OfflineMapManager offlineMapManager;
    private final MethodChannel mapChannel;
    private final String cityName;

    public OfflineAmap(Context context, MethodChannel mapChannel, String cityName) throws Exception {
        this.offlineMapManager = new OfflineMapManager(context, this);
        this.mapChannel = mapChannel;
        this.cityName = cityName;
    }

    /**
     * 开始下载或更新离线地图
     */
    public void startDownload() throws AMapException {
        offlineMapManager.stop();
        boolean isProvinceCity = isProvinceCity();
        Log.i("离线地图", (isProvinceCity ? "直辖市" : "非直辖市") + " => " + cityName);
        boolean isDownloading = (isProvinceCity ? isDownloadingForProvince() : isDownloadingForCity());
        boolean isDownloaded = (isProvinceCity ? isDownloadedForProvince() : isDownloadedForCity());
//        Log.i("离线地图", "下载中 => " + isDownloading + ", 已下载 => " + isDownloaded);
        if (!isDownloading) {
            if (isDownloaded) {
                checkNewOfflineMap();
            } else {
                downloadOfflineMap();
            }
        }
    }

    /**
     * 判断是否已存在离线地图
     *
     * @return
     */
    public boolean hasOfflineMap() {
        return (isProvinceCity() ? isDownloadedForProvince() : isDownloadedForCity());
    }

    /**
     * 销毁离线地图管理器
     */
    public void destroy() {
        offlineMapManager.destroy();
    }

    /**
     * 是否为直辖市
     *
     * @return
     */
    private boolean isProvinceCity() {
        return cityName.startsWith("北京") || cityName.startsWith("上海") || cityName.startsWith("天津") || cityName.startsWith("重庆");
    }

    /**
     * 判断是否在下载中(城市)
     *
     * @return
     */
    private boolean isDownloadingForCity() {
        boolean downloading = false;
        Iterator<OfflineMapCity> downloadingIterator = offlineMapManager.getDownloadingCityList().iterator();
        while (downloadingIterator.hasNext() && !downloading) {
            downloading = downloadingIterator.next().getCity().equals(cityName);
        }
        return downloading;
    }

    /**
     * 判断是否在下载中(省份)
     *
     * @return
     */
    private boolean isDownloadingForProvince() {
        boolean downloading = false;
        Iterator<OfflineMapProvince> downloadingIterator = offlineMapManager.getDownloadingProvinceList().iterator();
        while (downloadingIterator.hasNext() && !downloading) {
            downloading = downloadingIterator.next().getProvinceName().equals(cityName);
        }
        return downloading;
    }

    /**
     * 判断是否已下载(城市)
     *
     * @return
     */
    private boolean isDownloadedForCity() {
        boolean downloaded = false;
        Iterator<OfflineMapCity> downloadIterator = offlineMapManager.getDownloadOfflineMapCityList().iterator();
        Log.i("离线地图(城市)", offlineMapManager.getDownloadOfflineMapCityList().toString());
        while (downloadIterator.hasNext() && !downloaded) {
            downloaded = downloadIterator.next().getCity().equals(cityName);
        }
        return downloaded;
    }

    /**
     * 判断是否已下载(省份)
     *
     * @return
     */
    private boolean isDownloadedForProvince() {
        boolean downloaded = false;
        Iterator<OfflineMapProvince> downloadIterator = offlineMapManager.getDownloadOfflineMapProvinceList().iterator();
        Log.i("离线地图(省份)", offlineMapManager.getDownloadOfflineMapProvinceList().toString());
        while (downloadIterator.hasNext() && !downloaded) {
            downloaded = downloadIterator.next().getProvinceName().equals(cityName);
        }
        return downloaded;
    }

    /**
     * 请求检查是否有新版离线地图数据
     *
     * @throws AMapException
     */
    private void checkNewOfflineMap() throws AMapException {
        if (isProvinceCity()) {
            offlineMapManager.updateOfflineMapProvinceByName(cityName);
        } else {
            offlineMapManager.updateOfflineCityByName(cityName);
        }
    }

    /**
     * 请求下载离线地图数据
     *
     * @throws AMapException
     */
    private void downloadOfflineMap() throws AMapException {
        if (isProvinceCity()) {
            offlineMapManager.downloadByProvinceName(cityName);
            Log.i("离线地图", "请求下载离线地图数据 => Province");
        } else {
            offlineMapManager.downloadByCityName(cityName);
            Log.i("离线地图", "请求下载离线地图数据 => City");
        }
    }

    @Override
    public void onDownload(int status, int completeCode, String name) {
//        Log.i("离线地图", "下载状态 => status: " + status + ", completeCode: " + completeCode + ", name: " + name);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", status);
        map.put("completeCode", completeCode);
        map.put("name", name);
        mapChannel.invokeMethod("downloadProgress", map);
        if (status == OfflineMapStatus.EXCEPTION_SDCARD || status == OfflineMapStatus.START_DOWNLOAD_FAILD || status == OfflineMapStatus.SUCCESS) {
            destroy();
        } else if (status == OfflineMapStatus.NEW_VERSION) {
            try {
                startDownload();
            } catch (AMapException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onCheckUpdate(boolean hasNew, String name) {
        if (hasNew) {
            try {
                offlineMapManager.remove(name);
                downloadOfflineMap();
            } catch (AMapException e) {
                Log.i("离线地图异常", Objects.requireNonNull(e.getMessage()));
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onRemove(boolean success, String name, String describe) {
    }
}
